<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Menus &amp; toolbars in Ruby GTK</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="GUI, GTK, menus, toolbars, Ruby, programming, Linux">
<meta name="description" content="In this chapter of the Ruby GTK tutorial, we work
with Menus &amp; toolbars.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container2">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content2">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Menus &amp; toolbars</h1>

<p>
In this part of the Ruby GTK programming tutorial, we will work with menus &amp; toolbars.
</p>

<div class="big_hor">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* big_horizontal */
google_ad_slot = "2904953388";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<p>
A <b>menubar</b> is one of the most common parts of the GUI application. It is a group of commands 
located in various menus.
While in console applications you have to remember all those arcane commands, 
here we have most of the commands grouped into logical parts. These are accepted standards 
that further reduce the amount of time spending to learn a new application. 
</p>


<h2>Simple menu</h2>

<p>
In our first example, we will create a menubar with one file menu. 
The menu will have only one menu item. By selecting the item the application quits. 
</p>


<pre class="code">
#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a simple menu
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp &lt; Gtk::Window

    def initialize
        super
    
        set_title "Simple menu"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 250, 200
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        modify_bg Gtk::STATE_NORMAL, Gdk::Color.new(6400, 6400, 6440)
        
        mb = Gtk::MenuBar.new

        filemenu = Gtk::Menu.new
        filem = Gtk::MenuItem.new "File"
        filem.set_submenu filemenu
       
        exit = Gtk::MenuItem.new "Exit"
        exit.signal_connect "activate" do
            Gtk.main_quit
        end
        
        filemenu.append exit

        mb.append filem

        vbox = Gtk::VBox.new false, 2
        vbox.pack_start mb, false, false, 0

        add vbox
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main
</pre>

<p>
This is a small example with minimal menubar functionality.
</p>

<pre class="explanation">
mb = Gtk::MenuBar.new
</pre>

<p>
<code>MenuBar</code> widget is created. This is a container
for the menus. 
</p>

<pre class="explanation">
filemenu = Gtk::Menu.new
filem = Gtk::MenuItem.new "File"
filem.set_submenu filemenu
</pre>

<p>
Toplevel <code>MenuItem</code> is created. 
</p>

<pre class="explanation">
exit = Gtk::MenuItem.new "Exit"
exit.signal_connect "activate" do
    Gtk.main_quit
end

filemenu.append exit
</pre>

<p>
Exit <code>MenuItem</code> is created and appended to the
File <code>MenuItem</code>.
</p>

<pre class="explanation">
mb.append filem
</pre>

<p>
Toplevel <code>MenuItem</code> is appended to the <code>MenuBar</code>
widget. 
</p>

<pre class="explanation">
vbox = Gtk::VBox.new false, 2
vbox.pack_start mb, false, false, 0
</pre>

<p>
Unlike in other toolkits, we have to take care of the layout management of the menubar
ourselves. We put the menubar into the vertical box. 
</p>

<img src="/img/gui/rubygtk/simplemenu.png" alt="Simple menu">
<div class="figure">Figure: Simple menu</div>



<h2>Submenu</h2>

<p>
Our final example demonstrates how to create a submenu.
</p>

<pre class="code">
#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a submenu
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp &lt; Gtk::Window

    def initialize
        super
    
        set_title "Submenu"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 250, 200
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        modify_bg Gtk::STATE_NORMAL, Gdk::Color.new(6400, 6400, 6440)
        
        mb = Gtk::MenuBar.new

        filemenu = Gtk::Menu.new
        filem = Gtk::MenuItem.new "File"
        filem.set_submenu filemenu

        mb.append filem
        
        imenu = Gtk::Menu.new

        importm = Gtk::MenuItem.new "Import"
        importm.set_submenu imenu

        inews = Gtk::MenuItem.new "Import news feed..."
        ibookmarks = Gtk::MenuItem.new "Import bookmarks..."
        imail = Gtk::MenuItem.new "Import mail..."

        imenu.append inews
        imenu.append ibookmarks
        imenu.append imail

        filemenu.append importm
        
        exit = Gtk::MenuItem.new "Exit"
        exit.signal_connect "activate" do
            Gtk.main_quit
        end
        
        filemenu.append exit

        vbox = Gtk::VBox.new false, 2
        vbox.pack_start mb, false, false, 0

        add vbox
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main
</pre>

<p>
Submenu creation. 
</p>

<pre class="explanation">
imenu = Gtk::Menu.new
</pre>

<p>
A submenu is a <code>Menu</code>. 
</p>

<pre class="explanation">
importm = Gtk::MenuItem.new "Import"
importm.set_submenu imenu
</pre>

<p>
It is a submenu of a menu item, which belogs to toplevel
file menu. 
</p>

<pre class="explanation">
inews = Gtk::MenuItem.new "Import news feed..."
ibookmarks = Gtk::MenuItem.new "Import bookmarks..."
imail = Gtk::MenuItem.new "Import mail..."

imenu.append inews
imenu.append ibookmarks
imenu.append imail
</pre>

<p>
Submenu has its own menu items. 
</p>

<img src="/img/gui/rubygtk/submenu.png" alt="Submenu">
<div class="figure">Figure: Submenu</div>


<h2>Image menu</h2>

<p>
In the next example, we will further explore the menus.
We will add images and accelerators to our menu items. 
<b>Accelerators</b> are keyboard shortcuts for activating a menu item. 
</p>

<pre class="code">
#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a menu with
# images, accelerators and a separator
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp &lt; Gtk::Window

    def initialize
        super
    
        set_title "Image menu"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 250, 200
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        modify_bg Gtk::STATE_NORMAL, Gdk::Color.new(6400, 6400, 6440)
        
        mb = Gtk::MenuBar.new

        filemenu = Gtk::Menu.new
        filem = Gtk::MenuItem.new "File"
        filem.set_submenu filemenu
        
        agr = Gtk::AccelGroup.new
        add_accel_group agr

        newi = Gtk::ImageMenuItem.new Gtk::Stock::NEW, agr
        key, mod = Gtk::Accelerator.parse "N"
        newi.add_accelerator("activate", agr, key, 
            mod, Gtk::ACCEL_VISIBLE)
        filemenu.append newi

        openm = Gtk::ImageMenuItem.new Gtk::Stock::OPEN, agr
        key, mod = Gtk::Accelerator.parse "O"
        openm.add_accelerator("activate", agr, key, 
            mod, Gtk::ACCEL_VISIBLE)
        filemenu.append openm

        sep = Gtk::SeparatorMenuItem.new
        filemenu.append sep

        exit = Gtk::ImageMenuItem.new Gtk::Stock::QUIT, agr
        key, mod = Gtk::Accelerator.parse "Q"
        exit.add_accelerator("activate", agr, key, 
            mod, Gtk::ACCEL_VISIBLE)

        exit.signal_connect "activate" do
            Gtk.main_quit
        end
        filemenu.append exit

        mb.append filem

        vbox = Gtk::VBox.new false, 2
        vbox.pack_start mb, false, false, 0

        add vbox
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main
</pre>

<p>
Our example shows a toplevel menu item with three sublevel menu items. Each of the
menu items has a image and an accelerator. The accelerator for the quit menu item
is active. 
</p>

<pre class="explanation">
agr = Gtk::AccelGroup.new
add_accel_group agr
</pre>

<p>
To work with accelerators, we create a global <code>AccelGroup</code>
object. It will be used later.  
</p>

<pre class="explanation">
newi = Gtk::ImageMenuItem.new Gtk::Stock::NEW, agr
key, mod = Gtk::Accelerator.parse "N"
newi.add_accelerator("activate", agr, key, 
    mod, Gtk::ACCEL_VISIBLE)
filemenu.append newi
</pre>

<p>
<code>ImageMenuItem</code> is created. The image comes from the stock
of images. We create also a Ctrl+N accelerator. 
</p>

<pre class="explanation">
sep = Gtk::SeparatorMenuItem.new
filemenu.append sep
</pre>

<p>
These lines create a separator. It is used to put menu items
into logical groups. 
</p>

<img src="/img/gui/rubygtk/imagemenu.png" alt="Image menu">
<div class="figure">Figure: Image menu</div>

<p>
Menus group commands that we can use in application. 
Toolbars provide a quick access to the most frequently used commands. 
</p>


<h2>Simple toolbar</h2>

<p>
Next we create a simple toolbar. 
</p>


<pre class="code">
#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a toolbar
# widget
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp &lt; Gtk::Window

    def initialize
        super
    
        set_title "Toolbar"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 250, 200
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        toolbar = Gtk::Toolbar.new
        toolbar.set_toolbar_style Gtk::Toolbar::Style::ICONS

        newtb = Gtk::ToolButton.new Gtk::Stock::NEW
        opentb = Gtk::ToolButton.new Gtk::Stock::OPEN
        savetb = Gtk::ToolButton.new Gtk::Stock::SAVE
        sep = Gtk::SeparatorToolItem.new
        quittb = Gtk::ToolButton.new Gtk::Stock::QUIT

        toolbar.insert 0, newtb
        toolbar.insert 1, opentb
        toolbar.insert 2, savetb
        toolbar.insert 3, sep
        toolbar.insert 4, quittb
        
        quittb.signal_connect "clicked" do
            Gtk.main_quit
        end

        vbox = Gtk::VBox.new false, 2
        vbox.pack_start toolbar, false, false, 0

        add(vbox)
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main

</pre>

<p>
The example shows a toolbar and four tool buttons. 
</p>

<pre class="explanation">
toolbar = Gtk::Toolbar.new
</pre>

<p>
A <code>Toolbar</code> widget is created. 
</p>

<pre class="explanation">
toolbar.set_toolbar_style Gtk::Toolbar::Style::ICONS
</pre>

<p>
On toolbar, we show only icons. No text. 
</p>

<pre class="explanation">
newtb = Gtk::ToolButton.new Gtk::Stock::NEW
</pre>

<p>
A <code>ToolButton</code> with an image from
stock is created. The image comes from the built-in stock of
images. 
</p>

<pre class="explanation">
sep = Gtk::SeparatorToolItem.new
</pre>

<p>
This is a separator. It can be used to put toolbar buttons
into logical groups. 
</p>

<pre class="explanation">
toolbar.insert 0, newtb
toolbar.insert 1, opentb
...
</pre>

<p>
Toolbar buttons are inserted into the toolbar widget. 
</p>

<img src="/img/gui/rubygtk/toolbar.png" alt="Toolbar">
<div class="figure">Figure: Toolbar</div>



<h2>Undo redo</h2>

<p>
The following example demonstrates, how we can deactivate toolbar buttons on the toolbar.
It is a common practise in GUI programming. For example the save button.
If we save all changes of our document to the disk, the save button is deactivated 
in most text editors. This way the application indicates to the user, 
that all changes are already saved. 
</p>

<pre class="code">
#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows how to 
# activate/deactivate a ToolButton
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp &lt; Gtk::Window

    
    def initialize
        super
    
        set_title "Undo redo"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        @count = 2
        
        init_ui

        set_default_size 250, 200
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        toolbar = Gtk::Toolbar.new
        toolbar.set_toolbar_style Gtk::Toolbar::Style::ICONS

        @undo = Gtk::ToolButton.new Gtk::Stock::UNDO
        @redo = Gtk::ToolButton.new Gtk::Stock::REDO
        sep = Gtk::SeparatorToolItem.new
        quit = Gtk::ToolButton.new Gtk::Stock::QUIT

        toolbar.insert 0, @undo
        toolbar.insert 1, @redo
        toolbar.insert 2, sep
        toolbar.insert 3, quit
        
        @undo.signal_connect "clicked" do
            on_undo
        end
         
        @redo.signal_connect "clicked" do
            on_redo
        end
        
        quit.signal_connect "clicked" do
            Gtk.main_quit
        end

        vbox = Gtk::VBox.new false, 2
        vbox.pack_start toolbar, false, false, 0

        self.add vbox

    end
    
    def on_undo

        @count = @count - 1

        if @count &lt;= 0
            @undo.set_sensitive false
            @redo.set_sensitive true
        end
    end


    def on_redo
        @count = @count + 1

        if @count >= 5
            @redo.set_sensitive false
            @undo.set_sensitive true
        end
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main
</pre>

<p>
Our example creates undo and redo buttons from the GTK stock resources. 
After several clicks each of the buttons is deactivated. The buttons are grayed out.  
</p>

<pre class="explanation">
@count = 2
</pre>

<p>
The <code>@count</code> variable decides, which button is activated or
deactivated. 
</p>


<pre class="explanation">
@undo = Gtk::ToolButton.new Gtk::Stock::UNDO
@redo = Gtk::ToolButton.new Gtk::Stock::REDO
</pre>

<p>
We have two tool buttons. Undo and redo tool buttons. Images come from the stock
resources. 
</p>

<pre class="explanation">
@undo.signal_connect "clicked" do
    on_undo
end         
</pre>

<p>
Clicking on the undo button, we trigger the <code>on_undo</code> method.
</p>

<pre class="explanation">
if @count &lt;= 0
    @undo.set_sensitive false
    @redo.set_sensitive true
end
</pre>

<p>
To activate or deactivate a widget, we use the <code>set_sensitive</code> method
</p>

<img src="/img/gui/rubygtk/undoredo.png" alt="Undo redo">
<div class="figure">Figure: Undo redo</div>


<p>
In this chapter of the Ruby GTK tutorial, we showed, how to work with menus &amp; toolbars.
</p>


<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified June 26, 2009  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>
